package base.core.security.dms;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import lombok.SneakyThrows;

/**
 * @Description 拦截器配置
 * @Author Pengwei
 * @CreatDate 2022/1/10 17:05
 */
@Primary
@Configuration
@ConditionalOnProperty(name = "security.token",havingValue = "dms")
public class DmsWebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Value("${security.white-list:}")
    String[] whiteList; //白名单

    @Override
    @SneakyThrows
    protected void configure(HttpSecurity http) {
        //白名单设置
        setWhiteList(http, whiteList);

        http.exceptionHandling().authenticationEntryPoint(dmsUnAuthenticationEntryPoint()).and()// 授权异常处理
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()// 不创建和使用session
                .authorizeRequests().anyRequest().authenticated().and() //其余所有访问均拦截
                .addFilter(new DmsJwtAuthorizationFilter(authenticationManager())) //鉴权拦截器
                .csrf().disable() //取消scrf拦截,让非Get请求可以通过
                .headers().frameOptions().disable()//设置可以被Iframe内嵌
                ;
    }

    //设置白名单
    private void setWhiteList(HttpSecurity http, String[] writeList) throws Exception {
        if (ArrayUtils.isEmpty(writeList)) {
            return;
        }
        //去掉空字符串
        List<String> list = Arrays.stream(writeList).filter(v -> StringUtils.isNotBlank(v)).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        http.authorizeRequests().antMatchers(list.toArray(new String[list.size()])).permitAll();
    }

    /**
     * 鉴权错误处理
     */
    @Bean
    DmsUnAuthenticationEntryPoint dmsUnAuthenticationEntryPoint() {
        return new DmsUnAuthenticationEntryPoint();
    }
}
